package com.ubb.dbms.core.parser.visitors;

import java.util.ArrayList;
import java.util.List;

import net.sf.jsqlparser.statement.select.PlainSelect;
import net.sf.jsqlparser.statement.select.SelectExpressionItem;
import net.sf.jsqlparser.statement.select.SelectVisitor;
import net.sf.jsqlparser.statement.select.Union;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ubb.dbms.core.Utils.SQLExceptions.ItemNotExistsException;
import com.ubb.dbms.core.connection.result.MessageResult;
import com.ubb.dbms.core.parser.SQLQueryParser;
import com.ubb.dbms.domain.queryData.SelectElements;

public class SQLSelectVisitor implements SelectVisitor {
	private final Logger log = LoggerFactory.getLogger(SQLSelectVisitor.class);
	
	@Override
	public void visit(PlainSelect plainSelect) {
		SelectElements selectElements = new SelectElements();
		
		// set projections
		List<String> projectionList = new ArrayList<String>();
		
		List<SelectExpressionItem> selectItems = new ArrayList<SelectExpressionItem>(plainSelect.getSelectItems());
		try {
			SQLExpressionVisitor projectionVisitor = new SQLExpressionVisitor();
			for (SelectExpressionItem select : selectItems) {
				select.getExpression().accept(projectionVisitor);
			}
			selectElements.setProjections(projectionVisitor.getProjections());
		} catch (Exception e) { // All columns projection (*)
			selectElements.setProjections(new String[]{"*"});
		}
		
		// set tableNames
		SQLFromItemVisitor sqlFromVisitor = new SQLFromItemVisitor();
		plainSelect.getFromItem().accept(sqlFromVisitor);
		selectElements.setTableNames(new String[]{sqlFromVisitor.getTableName()}); // only one Table name (PlainSelect)
		
		// set conditions
		if (plainSelect.getWhere() != null) {
			SQLExpressionVisitor expressionAndConditionVisitor = new SQLExpressionVisitor();
			plainSelect.getWhere().accept(expressionAndConditionVisitor);
			selectElements.setCondition(expressionAndConditionVisitor.getConditions());
		
			// set logicalOperator
			selectElements.setLogicalOperator(expressionAndConditionVisitor.getLogicalOperator());
		}
		
		try {
			SQLQueryParser.getOperatorEvaluator().manageSelect(selectElements, SQLQueryParser.getDatabaseName());
		} catch (ItemNotExistsException e) {
			log.error("SELECT processing error.");
			MessageResult.sendMessage(MessageResult.MESSAGE_ERROR, "SELECT processing error.");
		}
	}

	@Override
	public void visit(Union arg0) {
		// TODO Auto-generated method stub
		
	}
}
